# -*- coding:utf-8 -*-
"""
自定义脚本的解析类
"""
import sys


class Output:  # 模拟输出
    def __init__(self):
        self.text = ''  # 新建空字符串

    def write(self, string):
        self.text += string

    def writelines(self, lines):
        for line in lines:
            self.write(line)


class Input:  # 模拟输入
    def __init__(self, input_string=''):  # 默认参数
        self.text = input_string

    def read(self, size=None):
        if size is None:
            res, self.text = self.text, ''
        else:
            res, self.text = self.text[:size], self.text[size:]
        return res

    def readline(self):
        eoln = self.text.find('\n')
        if eoln == -1:
            res, self.text = self.text, ''
        else:
            res, self.text = self.text[:eoln + 1], self.text[eoln + 1:]
        return res


def redirect(function, *args, **kwargs):
    save_streams = sys.stdin, sys.stdout  # 暂时保当前的流接口
    sys.stdin = Input()  # 将输入流导到自定义的类实例
    sys.stdout = Output()  # 将输出流导到自定义的类实例
    try:
        result = function(*args, **kwargs)
        output = sys.stdout.text  # 将输出流中的结果保存到output
    finally:
        sys.stdin, sys.stdout = save_streams  # 输出输入流重定向到原来的样子
    return (result, output)


# 已有一个函数test(),内容如下：
# def test():
#     m = input()
#     print('success:', m)
#     exec("print('success:test')")


# 测试：

# (result, output) = redirect(test, (), {}, '34534')  # 输入的5 加不加换行都可以，即'5'和'5\n'效果一样
# print(output)  # print会将换行符转义，输出后 会换行

"""
脚本中直接使用的变量
env.set("variable", "value");
env.get("variable", "value");
test("variable", "value");
request.body
response.body
response.status
"""


class CustomScript:
    def __init__(self, script, request=None, response=None, env=None, test=None, **kwargs):
        self.script = script
        self.request = request
        self.response = response
        self.env = env
        self.test = test

    def run_script(self):
        globals_env = {"request": self.request,
                       "response": self.response,
                       "env": self.env,
                       "test": self.test}
        locals_env = {}
        exec(self.script, globals_env, locals_env)

    # 变更流输出
    def run(self):
        try:
            (result, output) = redirect(self.run_script)
            self.request.console_out += output
        except Exception as e:
            # self.request.console_out += str(e)
            self.request.console_out += str(repr(e))
